import * as THREE from 'three'
import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js'
import { emit } from '../../../utils/EventBus.js'

// let camera, scene, renderer, controls
let controls

const objects = []

let raycaster

let moveForward = false
let moveBackward = false
let moveLeft = false
let moveRight = false
let canJump = false

let moveForce = 5
let jumpForce = 50
let force = new THREE.Vector3(0, 0, 0)
let gravity = 9.81

let prevTime = performance.now()
export const velocity = new THREE.Vector3()
const direction = new THREE.Vector3()
const vertex = new THREE.Vector3()
const color = new THREE.Color()

const personHeight = 1.7

export function fp() {
    const scene = window.threeScene
    const { renderer, camera, preRender } = scene.my

    // preRender.push(() => {
    //     animate()
    // })

    // scene.fog = new THREE.Fog(0xffffff, 0, 750)

    // const light = new THREE.HemisphereLight(0xeeeeff, 0x777788, 2.5)
    // light.position.set(0.5, 1, 0.75)
    // scene.add(light)

    controls = new PointerLockControls(camera, document.body)
    controls.pointerSpeed = 0.5

    // const blocker = document.getElementById('blocker')
    // const instructions = document.getElementById('instructions')

    const button = document.createElement('button')
    button.textContent = '第一人称'
    button.style.cssText = `
        position: fixed;
        top: 1%;
        right: 1%;
        text-align: center;
        z-index: 9999;
        `
    document.body.appendChild(button)




    button.addEventListener('click', function () {
        const camera = controls.getObject()
        // camera.position.y = personHeight
        camera.position.set(1, personHeight, 1)
        camera.lookAt(0, personHeight, 0)
        controls.lock()
    })

    controls.addEventListener('lock', function () {
        emit('collision', true)
        // instructions.style.display = 'none'
        // blocker.style.display = 'none'
    })

    controls.addEventListener('unlock', function () {
        emit('collision', false)
        // blocker.style.display = 'block'
        // instructions.style.display = ''
    })

    scene.add(controls.object)

    const onKeyDown = function (event) {
        switch (event.code) {
            case 'ArrowUp':
            case 'KeyW':
                moveForward = true
                break

            case 'ArrowLeft':
            case 'KeyA':
                moveLeft = true
                break

            case 'ArrowDown':
            case 'KeyS':
                moveBackward = true
                break

            case 'ArrowRight':
            case 'KeyD':
                moveRight = true
                break

            case 'Space':
                if (canJump === true) {
                    force.y += 0.016 * jumpForce * 1.5
                    //  velocity.y += 350
                }
                canJump = false
                break
        }
    }

    const onKeyUp = function (event) {
        switch (event.code) {
            case 'ArrowUp':
            case 'KeyW':
                moveForward = false
                break

            case 'ArrowLeft':
            case 'KeyA':
                moveLeft = false
                break

            case 'ArrowDown':
            case 'KeyS':
                moveBackward = false
                break

            case 'ArrowRight':
            case 'KeyD':
                moveRight = false
                break
        }
    }

    document.addEventListener('keydown', onKeyDown)
    document.addEventListener('keyup', onKeyUp)

    raycaster = new THREE.Raycaster(
        new THREE.Vector3(),
        new THREE.Vector3(0, -1, 0),
        0,
        10
    )
}

export function animate(mcc) {
    const time = performance.now()

    if (controls.isLocked === true) {
        raycaster.ray.origin.copy(controls.object.position)
        raycaster.ray.origin.y -= 10

        const intersections = raycaster.intersectObjects(objects, false)

        const onObject = intersections.length > 0

        const delta = (time - prevTime) / 1000

        velocity.x -= velocity.x * 10.0 * delta
        velocity.z -= velocity.z * 10.0 * delta

        // velocity.y -= 9.8 * 100.0 * delta // 100.0 = mass

        direction.z = Number(moveForward) - Number(moveBackward)
        direction.x = Number(moveRight) - Number(moveLeft)
        direction.normalize() // this ensures consistent movements in all directions

        const myRate = 50
        if (moveForward || moveBackward)
            velocity.z -= direction.z * myRate * delta
        if (moveLeft || moveRight) velocity.x -= direction.x * myRate * delta

        // my
        velocity.delta = delta
        // updateVelocityFromInput(delta * 0.1, mcc)

        /*
        if (onObject === true) {
            velocity.y = Math.max(0, velocity.y)
            canJump = true
        }

        // controls.moveRight(-velocity.x * delta)
        // controls.moveForward(-velocity.z * delta)

        controls.object.position.y += velocity.y * delta // new behavior

        if (controls.object.position.y < personHeight) {
            velocity.y = 0
            controls.object.position.y = personHeight

            canJump = true
        }

            */
    }

    prevTime = time

    // renderer.render(scene, camera)
}

export function updateVelocityFromInput(delta, mcc) {
    // Set vertical velocity to zero if grounded

    // here
    if (mcc.characterController.computedGrounded()) {
        velocity.y = 0
        canJump === true
    }

    // Reset force to zero
    force.set(0, 0, 0)

    // Add force relative to zero radians/degrees (visually 90° counterclockwise)
    // if (this.keys['KeyW'] == true) this.force.x = -delta * this.moveForce
    // if (this.keys['KeyA'] == true) this.force.z = delta * this.moveForce
    // if (this.keys['KeyS'] == true) this.force.x = delta * this.moveForce
    // if (this.keys['KeyD'] == true) this.force.z = -delta * this.moveForce
    // if (this.keys['Space'] == true && this.isJumping() == false) {
    //     this.jumping = true
    //     this.force.y += delta * this.jumpForce * 1.5
    // }

    // Rotate force by camera world direction
    // this.camera.getWorldDirection(this.direction)
    // this.angle = Math.PI - Math.atan2(this.direction.z, this.direction.x)

    // this.force.applyAxisAngle({ x: 0, y: 1, z: 0 }, this.angle)

    // Add new force to current velocity
    velocity.add(force)

    // Simulate gravity and damping
    velocity.y -= (delta * gravity) / 9.81
    // if(this.velocity.y){
    return

    // }
    this.velocity.z *= 0.5
    this.velocity.x *= 0.5

    // Clamp directional velocity
    this.velocity._y = this.velocity.y
    this.velocity.y = 0 // Ignore gravity velocity
    this.velocity.clampLength(-this.moveForce * delta, this.moveForce * delta)
    this.velocity.y = this.velocity._y

    // console.log("", this.velocity.x)
}
